﻿using System;
using System.IO;
using System.Linq;
using System.Windows.Media.Imaging;
using Autodesk.AutoCAD.Runtime;
using Autodesk.Windows;

namespace AutoCADDotNetLibrary
{
    /// <summary>
    /// <see cref="RibbonButton"/>扩展
    /// </summary>
    public static class RibbonButtonAtt
    {
        private static RibbonButton _ribbonButtonType;
        private static Type _type;

        /// <summary>
        /// 设置类型
        /// </summary>
        /// <param name="ribbonButton"></param>
        /// <param name="t">具有<see cref="RibbonButtonAttribute"/>的方法类型</param>
        public static void SetType(RibbonButton ribbonButton, Type t)
        {
            // 目的是忽略Type和Index的顺序
            if (ribbonButton == _ribbonButtonIndex)//设置了Index
            {
                ribbonButton.SetByType(t, _index);
            }
            else
            {
                _ribbonButtonType = ribbonButton;
                _type = t;
            }
        }

        private static RibbonButton _ribbonButtonIndex;
        private static int _index;
        /// <summary>
        /// 设置Index
        /// </summary>
        /// <param name="ribbonButton"></param>
        /// <param name="index">位置</param>
        public static void SetIndex(RibbonButton ribbonButton, int index)
        {
            // 目的是忽略Type和Index的顺序
            if (ribbonButton == _ribbonButtonType)//设置了Type
            {
                ribbonButton.SetByType(_type, index);
            }
            else
            {
                _ribbonButtonIndex = ribbonButton;
                _index = index;
            }
        }

        /// <summary>
        /// 设置<see cref="RibbonButton"/>样式
        /// </summary>
        /// <param name="ribbonButton"></param>
        /// <param name="style"><see cref="RibbonButton"/>样式</param>
        public static void SetRibbonButtonStyle(RibbonButton ribbonButton, Autodesk.AutoCAD.Customization.RibbonButtonStyle style)
        {
            ribbonButton.ShowImage = true;
            if (style == Autodesk.AutoCAD.Customization.RibbonButtonStyle.LargeWithText ||
                style == Autodesk.AutoCAD.Customization.RibbonButtonStyle.SmallWithText ||
                style == Autodesk.AutoCAD.Customization.RibbonButtonStyle.LargeWithHorizontalText)
            {
                ribbonButton.ShowText = true;
            }
            else
            {
                ribbonButton.ShowText = false;
            }
            if (style == Autodesk.AutoCAD.Customization.RibbonButtonStyle.SmallWithText ||
                style == Autodesk.AutoCAD.Customization.RibbonButtonStyle.SmallWithoutText)
            {
                ribbonButton.Size = RibbonItemSize.Standard;
            }
            else
            {
                ribbonButton.Size = RibbonItemSize.Large;
            }
            if (style == Autodesk.AutoCAD.Customization.RibbonButtonStyle.LargeWithHorizontalText)
            {
                ribbonButton.Orientation = System.Windows.Controls.Orientation.Horizontal;
            }
            else
            {
                ribbonButton.Orientation = System.Windows.Controls.Orientation.Vertical;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ribbonButton"></param>
        /// <param name="t"></param>
        /// <param name="index"></param>
        private static void SetByType(this RibbonButton ribbonButton, Type t, int index)
        {
            if (t == null)
                return;

            var ribbonButtons = t.GetMethods().Select(x => new
            {
                RibbbonButtonAtt = x.GetCustomAttributes(typeof(RibbonButtonAttribute), false).OfType<RibbonButtonAttribute>(),
                Command = x.GetCustomAttributes(typeof(CommandMethodAttribute), false).OfType<CommandMethodAttribute>()
            }).Where(x => x.RibbbonButtonAtt.Count() != 0 && x.Command.Count() != 0)
               .Select(x => new
               {
                   Command = x.Command.First(),
                   RibbbonButtonAtt = x.RibbbonButtonAtt.First()
               }).ToList();

            var first = ribbonButtons.FirstOrDefault(x => x.RibbbonButtonAtt.Index == index);
            if (first == null)
                return;

            //赋值
            ribbonButton.Id = first.RibbbonButtonAtt.UId;
            ribbonButton.Text = first.RibbbonButtonAtt.Text;
            SetRibbonButtonStyle(ribbonButton, first.RibbbonButtonAtt.RibbonButtonStyle);

            if (!string.IsNullOrEmpty(first.RibbbonButtonAtt.SmallImage))
            {
                if (first.RibbbonButtonAtt.SmallImage.StartsWith("pack://application:,,,/"))
                {
                    ribbonButton.Image = new BitmapImage(new Uri(first.RibbbonButtonAtt.SmallImage));
                }
                else
                {
                    ribbonButton.Image = new BitmapImage(new Uri($"pack://application:,,,/{Path.GetFileNameWithoutExtension(t.Assembly.Location)};component/{first.RibbbonButtonAtt.SmallImage}"));
                }
            }
            if (!string.IsNullOrEmpty(first.RibbbonButtonAtt.LargeImage))
            {
                if (first.RibbbonButtonAtt.LargeImage.StartsWith("pack://application:,,,/"))
                {
                    ribbonButton.LargeImage = new BitmapImage(new Uri(first.RibbbonButtonAtt.LargeImage));
                }
                else
                {
                    ribbonButton.LargeImage = new BitmapImage(new Uri($"pack://application:,,,/{Path.GetFileNameWithoutExtension(t.Assembly.Location)};component/{first.RibbbonButtonAtt.LargeImage}"));
                }
            }

            ribbonButton.CommandParameter = first.Command.GlobalName;
            ribbonButton.CommandHandler = RibbonCommand.Instance;

            //RibbonToolTipManage
            if (first.RibbbonButtonAtt.IsUseRibbonToolTipManage && RibbonToolTipManage.Instance != null)
            {
                ribbonButton.ToolTip = RibbonToolTipManage.Instance.CreateRibbonToolTip(first.Command, first.RibbbonButtonAtt);
            }
        }
    }
}
